Author: Katarina Dragicevic (PhD student), Biotech Research and Innovation Centre, University of Copenhagen

This notebook is about how the Cacoa pipeline was ran on different Conos objects (P15/P60 excitatory/inhibitory) The same pipeline was used for all objects and we show here on 1 example how it was done.

  1. Load Conos object and annotation file. Construct the sample groups objects. Load color palettes.

#we changed some of the annotation names after we ran Cacoa already on the objects. This is why we use this recvec to recode the names for the final plots to make them match those in the paper

recvec <- (setNames(c(‘Sst_Crhr2’, ‘Sst_Crh’, ‘Sst_Nr2f2_Cdh9’, ‘Sst_Hpse’, ‘Sst_Nr2f2_Glra3’, ‘Pvalb_Kcnk10’, ‘Pvalb_Gpc6’, ‘Pvalb_Sema5a’, ‘Pvalb_Gpr149’, ‘Pvalb_Tacr1’, ‘Pvalb_Calb1’, ‘Sst_Necab1’, ‘Vip_Chat’, ‘Pvalb_Htr2c’, ‘Vip_Col15a1’, ‘Id2_Car10’, ‘Id2_Car2’, ‘Id2_Ano3’, ‘Sst_Calb2’, ‘Sst_Piezo2’, ‘Sst_Nr2f2_Necab1’, ‘Sst_Chodl’, ‘Pvalb_Vipr2’, ‘Lamp5_Lhx6’, ‘Vip_Thsd7b’, ‘Lamp5_Lsp1’, ‘Vip_Sgcz’, ‘Vip_Gpc3’, ‘Lamp5_Dock5’, ‘Pvalb_Gabrg1’, ‘Lamp5_Ndst4’), ci60$cell.groups %>% unique %>% as.character()))

recvec
               Sst_Crhr2                  Sst_Crh           Sst_Nr2f2_Cdh9                 Sst_Hpse 
             "Sst_Crhr2"                "Sst_Crh"         "Sst_Nr2f2_Cdh9"               "Sst_Hpse" 
         Sst_Nr2f2_Glra3      Pvalb_Sema3e_Kcnk10               Pvalb_Gpc6        Pvalb_Reln_Sema5a 
       "Sst_Nr2f2_Glra3"           "Pvalb_Kcnk10"             "Pvalb_Gpc6"           "Pvalb_Sema5a" 
            Pvalb_Gpr149     Pvalb_Tacr1_Il1rapl2       Pvalb_Calb1_Necab1               Sst_Necab1 
          "Pvalb_Gpr149"            "Pvalb_Tacr1"            "Pvalb_Calb1"             "Sst_Necab1" 
                Vip_Chat Pvalb_Calb1_Necab1_Htr2c              Vip_Col15a1                Id2_Car10 
              "Vip_Chat"            "Pvalb_Htr2c"            "Vip_Col15a1"              "Id2_Car10" 
                Id2_Car2                 Id2_Ano3                Sst_Calb2         Sst_Mme_Fam114a1 
              "Id2_Car2"               "Id2_Ano3"              "Sst_Calb2"             "Sst_Piezo2" 
        Sst_Nr2f2_Necab1                Sst_Chodl              Pvalb_Vipr2               Lamp5_Lhx6 
      "Sst_Nr2f2_Necab1"              "Sst_Chodl"            "Pvalb_Vipr2"             "Lamp5_Lhx6" 
       Vip_Thsd7b_Prss12               Lamp5_Lsp1                 Vip_Sgcz                 Vip_Gpc3 
            "Vip_Thsd7b"             "Lamp5_Lsp1"               "Vip_Sgcz"               "Vip_Gpc3" 
             Lamp5_Dock5             Pvalb_Gabrg1         Lamp5_Ntn1_Ndst4 
           "Lamp5_Dock5"           "Pvalb_Gabrg1"            "Lamp5_Ndst4" 

#library(cacoa)

#library(qs)

#con <- qread(“inhibitory_p60.qs”, nthreads = 5) #conos object

#anno <- qread(“anno_inhibitory_p60.qs”, nthreads = 1) #annotation

#sg.pal <- qread(“sg.pal_inhibitory_p60.qs”, nthreads = 1) #palette for sample groups

#cg.pal <- qread(“cg.pal_inhibitory_p60.qs”, nthreads = 1) #palette for cell groups

#sg <- qread(“sg_inhibitory_p60.qs”, nthreads = 1) #sample groups

#how does sg look like?
sg
           1014_WT           1099_15q P60_AAM1033_15q_b3 P60_AAM1035_15q_b3 P60_AAM1037_15q_b3  P60_AAM11a_15q_b1 
                wt                15q                15q                15q                15q                15q 
  P60_AAM11a_wt_b1  P60_AAM11b_15q_b1   P60_AAM11b_wt_b1     P60_AAM3_wt_b1     P60_AAM8_wt_b1  P60_AAM978_15q_b3 
                wt                15q                 wt                 wt                 wt                15q 
  P60_AAMT2_15q_b2   P60_AAMT3_15q_b2    P60_AAMW1_wt_b2    P60_AAMW2_wt_b2 
               15q                15q                 wt                 wt 
Levels: 15q wt
#how does sg.pal look like?
sg.pal
          15q            wt 
"dodgerblue2"       "black" 
#how does cg.pal look like?
cg.pal
        Id2_Ano3        Id2_Car10         Id2_Car2      Lamp5_Dock5       Lamp5_Lhx6       Lamp5_Lsp1      Lamp5_Ndst4 
       "#e07ba9"        "#a9e07b"        "#857be0"        "#a5e07b"        "#7be096"        "#e0c97b"        "#e07bc4" 
     Pvalb_Calb1     Pvalb_Gabrg1       Pvalb_Gpc6     Pvalb_Gpr149      Pvalb_Htr2c     Pvalb_Kcnk10     Pvalb_Sema5a 
       "#7b92e0"        "#a0e07b"        "#7be0d4"        "#e07b87"        "#afe07b"        "#ac7be0"        "#e07b94" 
     Pvalb_Tacr1      Pvalb_Vipr2        Sst_Calb2        Sst_Chodl          Sst_Crh        Sst_Crhr2         Sst_Hpse 
       "#e0b67b"        "#e0997b"        "#8fe07b"        "#cc7be0"        "#7bc1e0"        "#b5e07b"        "#e07b82" 
      Sst_Necab1   Sst_Nr2f2_Cdh9  Sst_Nr2f2_Glra3 Sst_Nr2f2_Necab1       Sst_Piezo2         Vip_Chat      Vip_Col15a1 
       "#a67be0"        "#e0c27b"        "#cbe07b"        "#7be0c2"        "#7bb3e0"        "#e07bc3"        "#7b91e0" 
        Vip_Gpc3         Vip_Sgcz       Vip_Thsd7b 
       "#7be08e"        "#7b9ae0"        "#e0c17b" 

UMAP

#cao$plotEmbedding(color.by = “cell.groups”, font.size = 3)

UMAP colored by sample

#cao$plotEmbedding(color.by = “sample”, font.size = 0)

Cell group proportions

#cao$plotCellGroupSizes()

Cell loadings

#cao$estimateCellLoadings()

p2 %>% ggplot( aes( x = values, y = ind, color = ind)) +
  geom_violin(scale = "width", 
                #fill = "#ededed", 
                color = NA, aes(fill = ind), alpha = 0.2) +
  theme_light() + theme(legend.position = "none") + scale_fill_manual(values = palcomp) +
  geom_vline(xintercept = 0, linewidth = 0.1) +
  new_scale_fill() + 
  stat_summary(fun.data = iqr, geom = "errorbar", show.legend = F, 
               aes(color = ind), 
               stroke = 0.5, alpha = 0.9,color = "grey30", width = 0.25) + 
  stat_summary(fun.data = iqr, geom = "point", show.legend = F,
               aes(fill = ind), 
               shape = 23, stroke = 0.5, color = "grey30", alpha = 0.9, size = 2.5) +  
  scale_fill_manual(values = palcomp)
Warning: Ignoring unknown parameters: `stroke`

Cell Density

#cao$estimateCellDensity(method = “graph”)

#cao$estimateDiffCellDensity(type = “wilcox”, n.cores = 200)

cao$plotDiffCellDensity(type = "wilcox", min.z = 0, adjust.pvalues = T,  contours = c("Sst_Nr2f2_Glra3", "Pvalb_Vipr2"), contour.conf = "20%")

  |                                                                                                    |   0%, ETA NA
  |================================================                                                 |  50%, ETA 00:02
  |=============================================================================================| 100%, Elapsed 00:03

Expression shifts

#cao$estimateExpressionShiftMagnitudes(top.n.genes = 300)

p3 %>% ggplot( aes( y = value, x = Type, color = Type)) +
  geom_violin(scale = "width", 
                #fill = "#ededed", 
                color = NA, aes(fill = Type), alpha = 0.2, 
              trim = F) +
  theme_light() + theme(legend.position = "none", axis.text.x = element_text(angle = 90, hjust = 1, vjust = 0.5), panel.grid.minor = element_blank(), panel.grid.major = element_blank()) + scale_color_manual(values = pal2)+ scale_fill_manual(values = pal2) +
  geom_hline(yintercept = 0, linewidth = 0.1) +
  stat_summary(fun.data = iqr, geom = "errorbar", show.legend = F, aes(color = Type), shape = 23, stroke = 0.5, alpha = 0.9,color = "grey30", width = 0.25) + 
  stat_summary(fun.data = iqr, geom = "point", show.legend = F,aes(fill = Type), shape = 23, stroke = 0.5, color = "grey30", alpha = 0.9) 
Warning: Ignoring unknown parameters: `shape` and `stroke`

Cluster free expression shifts

#cao$estimateClusterFreeExpressionShifts(n.cores = 200, gene.selection = “z”, normalize.both = T, n.top.genes = 300)

DEG analysis

#cao$estimateDEPerCellType(n.cores = 100, name = “edgeR”, n.cells.subsample = 5, resampling.method = “bootstrap”, n.resamplings = 20)

Gene ontology

#cao$estimateOntology(type = “GSEA”, name = “GSEA”, org.db =org.Mm.eg.db, verbose = T, n.cores = 200, de.name = “edgeR2”)

#cao$estimateOntology(type = "GSEA", name = "GSEA", org.db =org.Mm.eg.db, verbose = T, n.cores = 200, de.name = "edgeR2")
cao$plotOntologyHeatmap(name = "GSEA", genes = "all")
Loading required package: DOSE

DOSE v3.24.2  For help: https://yulab-smu.top/biomedical-knowledge-mining-book/

If you use DOSE in published research, please cite:
Guangchuang Yu, Li-Gen Wang, Guang-Rong Yan, Qing-Yu He. DOSE: an R/Bioconductor package for Disease Ontology Semantic and Enrichment analysis. Bioinformatics 2015, 31(4):608-609

LS0tCnRpdGxlOiAiQ2Fjb2EgYW5hbHlzaXMgd2Fsa3Rocm91Z2giCm91dHB1dDogaHRtbF9ub3RlYm9vawotLS0KCkF1dGhvcjogS2F0YXJpbmEgRHJhZ2ljZXZpYyAoUGhEIHN0dWRlbnQpLCBCaW90ZWNoIFJlc2VhcmNoIGFuZCBJbm5vdmF0aW9uIENlbnRyZSwgVW5pdmVyc2l0eSBvZiBDb3BlbmhhZ2VuCgpUaGlzIG5vdGVib29rIGlzIGFib3V0IGhvdyB0aGUgQ2Fjb2EgcGlwZWxpbmUgd2FzIHJhbiBvbiBkaWZmZXJlbnQgQ29ub3Mgb2JqZWN0cyAoUDE1L1A2MCBleGNpdGF0b3J5L2luaGliaXRvcnkpClRoZSBzYW1lIHBpcGVsaW5lIHdhcyB1c2VkIGZvciBhbGwgb2JqZWN0cyBhbmQgd2Ugc2hvdyBoZXJlIG9uIDEgZXhhbXBsZSBob3cgaXQgd2FzIGRvbmUuIAoKMS4gTG9hZCBDb25vcyBvYmplY3QgYW5kIGFubm90YXRpb24gZmlsZS4gQ29uc3RydWN0IHRoZSBzYW1wbGUgZ3JvdXBzIG9iamVjdHMuIExvYWQgY29sb3IgcGFsZXR0ZXMuCgoKI3dlIGNoYW5nZWQgc29tZSBvZiB0aGUgYW5ub3RhdGlvbiBuYW1lcyBhZnRlciB3ZSByYW4gQ2Fjb2EgYWxyZWFkeSBvbiB0aGUgb2JqZWN0cy4gVGhpcyBpcyB3aHkgd2UgdXNlIHRoaXMgcmVjdmVjIHRvIHJlY29kZSB0aGUgbmFtZXMgZm9yIHRoZSBmaW5hbCBwbG90cyB0byBtYWtlIHRoZW0gbWF0Y2ggdGhvc2UgaW4gdGhlIHBhcGVyCgpyZWN2ZWMgPC0gKHNldE5hbWVzKGMoJ1NzdF9DcmhyMicsICdTc3RfQ3JoJywgJ1NzdF9OcjJmMl9DZGg5JywgJ1NzdF9IcHNlJywgJ1NzdF9OcjJmMl9HbHJhMycsICdQdmFsYl9LY25rMTAnLCAnUHZhbGJfR3BjNicsICdQdmFsYl9TZW1hNWEnLCAnUHZhbGJfR3ByMTQ5JywgJ1B2YWxiX1RhY3IxJywgJ1B2YWxiX0NhbGIxJywgJ1NzdF9OZWNhYjEnLCAnVmlwX0NoYXQnLCAnUHZhbGJfSHRyMmMnLCAnVmlwX0NvbDE1YTEnLCAnSWQyX0NhcjEwJywgJ0lkMl9DYXIyJywgJ0lkMl9Bbm8zJywgJ1NzdF9DYWxiMicsICdTc3RfUGllem8yJywgJ1NzdF9OcjJmMl9OZWNhYjEnLCAnU3N0X0Nob2RsJywgJ1B2YWxiX1ZpcHIyJywgJ0xhbXA1X0xoeDYnLCAnVmlwX1Roc2Q3YicsICdMYW1wNV9Mc3AxJywgJ1ZpcF9TZ2N6JywgJ1ZpcF9HcGMzJywgJ0xhbXA1X0RvY2s1JywgJ1B2YWxiX0dhYnJnMScsICdMYW1wNV9OZHN0NCcpLCBjaTYwJGNlbGwuZ3JvdXBzICU+JSB1bmlxdWUgJT4lIGFzLmNoYXJhY3RlcigpKSkKCmBgYHtyfQojd2UgY2hhbmdlZCBzb21lIG9mIHRoZSBhbm5vdGF0aW9uIG5hbWVzIGFmdGVyIHdlIHJhbiBDYWNvYSBhbHJlYWR5IG9uIHRoZSBvYmplY3RzLiBUaGlzIGlzIHdoeSB3ZSB1c2UgdGhpcyByZWN2ZWMgdG8gcmVjb2RlIHRoZSBuYW1lcyBmb3IgdGhlIGZpbmFsIHBsb3RzIHRvIG1ha2UgdGhlbSBtYXRjaCB0aG9zZSBpbiB0aGUgcGFwZXIKCnJlY3ZlYyA8LSAoc2V0TmFtZXMoYygnU3N0X0NyaHIyJywgJ1NzdF9DcmgnLCAnU3N0X05yMmYyX0NkaDknLCAnU3N0X0hwc2UnLCAnU3N0X05yMmYyX0dscmEzJywgJ1B2YWxiX0tjbmsxMCcsICdQdmFsYl9HcGM2JywgJ1B2YWxiX1NlbWE1YScsICdQdmFsYl9HcHIxNDknLCAnUHZhbGJfVGFjcjEnLCAnUHZhbGJfQ2FsYjEnLCAnU3N0X05lY2FiMScsICdWaXBfQ2hhdCcsICdQdmFsYl9IdHIyYycsICdWaXBfQ29sMTVhMScsICdJZDJfQ2FyMTAnLCAnSWQyX0NhcjInLCAnSWQyX0FubzMnLCAnU3N0X0NhbGIyJywgJ1NzdF9QaWV6bzInLCAnU3N0X05yMmYyX05lY2FiMScsICdTc3RfQ2hvZGwnLCAnUHZhbGJfVmlwcjInLCAnTGFtcDVfTGh4NicsICdWaXBfVGhzZDdiJywgJ0xhbXA1X0xzcDEnLCAnVmlwX1NnY3onLCAnVmlwX0dwYzMnLCAnTGFtcDVfRG9jazUnLCAnUHZhbGJfR2FicmcxJywgJ0xhbXA1X05kc3Q0JyksIGNpNjAkY2VsbC5ncm91cHMgJT4lIHVuaXF1ZSAlPiUgYXMuY2hhcmFjdGVyKCkpKQpyZWN2ZWMKYGBgCgojbGlicmFyeShjYWNvYSkKCiNsaWJyYXJ5KHFzKQoKI2NvbiA8LSBxcmVhZCgiaW5oaWJpdG9yeV9wNjAucXMiLCBudGhyZWFkcyA9IDUpICNjb25vcyBvYmplY3QKCiNhbm5vIDwtIHFyZWFkKCJhbm5vX2luaGliaXRvcnlfcDYwLnFzIiwgbnRocmVhZHMgPSAxKSAjYW5ub3RhdGlvbgoKI3NnLnBhbCA8LSBxcmVhZCgic2cucGFsX2luaGliaXRvcnlfcDYwLnFzIiwgbnRocmVhZHMgPSAxKSAjcGFsZXR0ZSBmb3Igc2FtcGxlIGdyb3VwcwoKI2NnLnBhbCA8LSBxcmVhZCgiY2cucGFsX2luaGliaXRvcnlfcDYwLnFzIiwgbnRocmVhZHMgPSAxKSAjcGFsZXR0ZSBmb3IgY2VsbCBncm91cHMKCiNzZyA8LSBxcmVhZCgic2dfaW5oaWJpdG9yeV9wNjAucXMiLCBudGhyZWFkcyA9IDEpICAjc2FtcGxlIGdyb3VwcwoKCgpgYGB7cn0KbGlicmFyeShjYWNvYSkKbGlicmFyeShxcykKCiNjb24gPC0gcXJlYWQoImluaGliaXRvcnlfcDYwLnFzIiwgbnRocmVhZHMgPSA1KSAjY29ub3Mgb2JqZWN0CiNhbm5vIDwtIHFyZWFkKCJhbm5vX2luaGliaXRvcnlfcDYwLnFzIiwgbnRocmVhZHMgPSAxKSAjYW5ub3RhdGlvbgojc2cucGFsIDwtIHFyZWFkKCJzZy5wYWxfaW5oaWJpdG9yeV9wNjAucXMiLCBudGhyZWFkcyA9IDEpICNwYWxldHRlIGZvciBzYW1wbGUgZ3JvdXBzCiNjZy5wYWwgPC0gcXJlYWQoImNnLnBhbF9pbmhpYml0b3J5X3A2MC5xcyIsIG50aHJlYWRzID0gMSkgI3BhbGV0dGUgZm9yIGNlbGwgZ3JvdXBzCiNzZyA8LSBxcmVhZCgic2dfaW5oaWJpdG9yeV9wNjAucXMiLCBudGhyZWFkcyA9IDEpICAjc2FtcGxlIGdyb3VwcwoKI2hvdyBkb2VzIHNnIGxvb2sgbGlrZT8Kc2cKYGBgCgpgYGB7cn0KI2hvdyBkb2VzIHNnLnBhbCBsb29rIGxpa2U/CnNnLnBhbApgYGAKCgpgYGB7cn0KI2hvdyBkb2VzIGNnLnBhbCBsb29rIGxpa2U/CmNnLnBhbApgYGAKCgpgYGB7cn0KY2FvIDwtIENhY29hJG5ldyhkYXRhLm9iamVjdCA9IGNvbiwgCiAgICAgICAgICAgICAgICAgc2FtcGxlLmdyb3VwcyA9IHNnLCAKICAgICAgICAgICAgICAgICBjZWxsLmdyb3VwcyA9IGFubm8sIAogICAgICAgICAgICAgICAgIHJlZi5sZXZlbCA9ICJ3dCIsIHRhcmdldC5sZXZlbCA9ICIxNXEiLCAKICAgICAgICAgICAgICAgICBzYW1wbGUuZ3JvdXBzLnBhbGV0dGUgPSBzZy5wYWwsIAogICAgICAgICAgICAgICAgIGNlbGwuZ3JvdXBzLnBhbGV0dGUgPSBjZy5wYWwpCmBgYAoKVU1BUAoKI2NhbyRwbG90RW1iZWRkaW5nKGNvbG9yLmJ5ID0gImNlbGwuZ3JvdXBzIiwgZm9udC5zaXplID0gMykKCmBgYHtyfQpjYW8kcGxvdEVtYmVkZGluZyhjb2xvci5ieSA9ICJjZWxsLmdyb3VwcyIsIGZvbnQuc2l6ZSA9IDMpCmBgYApVTUFQIGNvbG9yZWQgYnkgc2FtcGxlCgojY2FvJHBsb3RFbWJlZGRpbmcoY29sb3IuYnkgPSAic2FtcGxlIiwgZm9udC5zaXplID0gMCkKCmBgYHtyfQpjYW8kcGxvdEVtYmVkZGluZyhjb2xvci5ieSA9ICJzYW1wbGUiLCBmb250LnNpemUgPSAwKQpgYGAKQ2VsbCBncm91cCBwcm9wb3J0aW9ucyAKCiNjYW8kcGxvdENlbGxHcm91cFNpemVzKCkKCmBgYHtyfQpjYW8kcGxvdENlbGxHcm91cFNpemVzKCkKYGBgCgoKQ2VsbCBsb2FkaW5ncwoKI2NhbyRlc3RpbWF0ZUNlbGxMb2FkaW5ncygpCgpgYGB7cn0KI2NhbyRlc3RpbWF0ZUNlbGxMb2FkaW5ncygpCnAyIDwtIGNhbyRwbG90Q2VsbExvYWRpbmdzKHNob3cucHZhbHMgPSBGKSRkYXRhCgpsaWJyYXJ5KGRhdGEudGFibGUpCnAyIDwtIGRhdGEudGFibGUocDIpCmx2bCA8LSBwMlssIGFicyhtZWRpYW4odmFsdWVzKSksIGJ5ID0gaW5kXVtvcmRlcigtVjEpLGluZF0gJT4lIGFzLmNoYXJhY3RlcigpCmxldmVscyhwMiRpbmQpIDwtIHJldihsdmwpCnAyJGluZCA8LSBmYWN0b3IocDIkaW5kLCBsZXZlbHMgPSByZXYobHZsKSkKCgoKcDIkaW5kIDwtIGZhY3RvcihyZWNvZGVfZmFjdG9yKHAyJGluZCwhISFyZWN2ZWMpLCBsZXZlbHMgPSBhcy5jaGFyYWN0ZXIodW5pcXVlKCByZWNvZGVfZmFjdG9yKHAyJGluZCwhISFyZWN2ZWMpKSkpCnBhbGNvbXAgPC0gc2V0TmFtZXMoaWZlbHNlKHAyWywgKG1lZGlhbih2YWx1ZXMpKSwgYnkgPSBpbmRdW29yZGVyKC1WMSksVjFdID4gMCwgImRvZGdlcmJsdWUyIiwgImdyZXk2MCIpLCBwMlssIChtZWRpYW4odmFsdWVzKSksIGJ5ID0gaW5kXVtvcmRlcigtVjEpLGluZF0pCnBhbGNvbXAyIDwtIHNldE5hbWVzKGlmZWxzZShwMlssIChtZWRpYW4odmFsdWVzKSksIGJ5ID0gaW5kXVtvcmRlcigtVjEpLFYxXSA+IDAsICJkYXJrYmx1ZSIsICJncmV5NTAiKSwgcDJbLCAobWVkaWFuKHZhbHVlcykpLCBieSA9IGluZF1bb3JkZXIoLVYxKSxpbmRdKQoKbGlicmFyeShnZ25ld3NjYWxlKQpwMiAlPiUgZ2dwbG90KCBhZXMoIHggPSB2YWx1ZXMsIHkgPSBpbmQsIGNvbG9yID0gaW5kKSkgKwogIGdlb21fdmlvbGluKHNjYWxlID0gIndpZHRoIiwgCiAgICAgICAgICAgICAgICAjZmlsbCA9ICIjZWRlZGVkIiwgCiAgICAgICAgICAgICAgICBjb2xvciA9IE5BLCBhZXMoZmlsbCA9IGluZCksIGFscGhhID0gMC4yKSArCiAgdGhlbWVfbGlnaHQoKSArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikgKyBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBwYWxjb21wKSArCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gMCwgbGluZXdpZHRoID0gMC4xKSArCiAgbmV3X3NjYWxlX2ZpbGwoKSArIAogIHN0YXRfc3VtbWFyeShmdW4uZGF0YSA9IGlxciwgZ2VvbSA9ICJlcnJvcmJhciIsIHNob3cubGVnZW5kID0gRiwgCiAgICAgICAgICAgICAgIGFlcyhjb2xvciA9IGluZCksIAogICAgICAgICAgICAgICBzdHJva2UgPSAwLjUsIGFscGhhID0gMC45LGNvbG9yID0gImdyZXkzMCIsIHdpZHRoID0gMC4yNSkgKyAKICBzdGF0X3N1bW1hcnkoZnVuLmRhdGEgPSBpcXIsIGdlb20gPSAicG9pbnQiLCBzaG93LmxlZ2VuZCA9IEYsCiAgICAgICAgICAgICAgIGFlcyhmaWxsID0gaW5kKSwgCiAgICAgICAgICAgICAgIHNoYXBlID0gMjMsIHN0cm9rZSA9IDAuNSwgY29sb3IgPSAiZ3JleTMwIiwgYWxwaGEgPSAwLjksIHNpemUgPSAyLjUpICsgIAogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IHBhbGNvbXApCmBgYAoKQ2VsbCBEZW5zaXR5CgojY2FvJGVzdGltYXRlQ2VsbERlbnNpdHkobWV0aG9kID0gImdyYXBoIikKCiNjYW8kZXN0aW1hdGVEaWZmQ2VsbERlbnNpdHkodHlwZSA9ICJ3aWxjb3giLCBuLmNvcmVzID0gMjAwKQoKYGBge3J9CiNjYW8kZXN0aW1hdGVDZWxsRGVuc2l0eShtZXRob2QgPSAiZ3JhcGgiKQojY2FvJGVzdGltYXRlRGlmZkNlbGxEZW5zaXR5KHR5cGUgPSAid2lsY294Iiwgbi5jb3JlcyA9IDIwMCkKY2FvJHBsb3REaWZmQ2VsbERlbnNpdHkodHlwZSA9ICJ3aWxjb3giLCBtaW4ueiA9IDAsIGFkanVzdC5wdmFsdWVzID0gVCwgIGNvbnRvdXJzID0gYygiU3N0X05yMmYyX0dscmEzIiwgIlB2YWxiX1ZpcHIyIiksIGNvbnRvdXIuY29uZiA9ICIyMCUiKQpgYGAKCgoKRXhwcmVzc2lvbiBzaGlmdHMKCiNjYW8kZXN0aW1hdGVFeHByZXNzaW9uU2hpZnRNYWduaXR1ZGVzKHRvcC5uLmdlbmVzID0gMzAwKQoKYGBge3J9CiN0aGlzIGlzIGFuIGV4YW1wbGUgb24gb25seSBpbmhpYml0b3J5IG5ldXJvbnMsIGluIHRoZSBwYXBlciB3ZSB1c2VkIGJvdGggZXhjaXRhdG9yeSBhbmQgaW5oaWJpdG9yeSBuZXVyb25zIGZvciB0aGUgcGxvdCBhdCBwNjAKCiNjYW8kZXN0aW1hdGVFeHByZXNzaW9uU2hpZnRNYWduaXR1ZGVzKHRvcC5uLmdlbmVzID0gMzAwKQpwYWwyIDwtIGNhbyRjZWxsLmdyb3Vwcy5wYWxldHRlCnAzIDwtIGNhbyRwbG90RXhwcmVzc2lvblNoaWZ0TWFnbml0dWRlcyh0eXBlID0gImJveCIpJGRhdGEKCnAzJFR5cGUgPC0gcmVjb2RlX2ZhY3RvcihwMyRUeXBlLCEhIXJlY3ZlYykKcDMgPC0gZGF0YS50YWJsZShwMykKcDNbLG1lZCA6PSBtZWRpYW4odmFsdWUpLCBieSA9IFR5cGVdCnAzJFR5cGUgPC0gZmFjdG9yKHAzJFR5cGUsIGxldmVscyA9IHAzW29yZGVyKG1lZCldJFR5cGUgJT4lIHVuaXF1ZSAlPiUgYXMuY2hhcmFjdGVyKCkpCgoKcDMgJT4lIGdncGxvdCggYWVzKCB5ID0gdmFsdWUsIHggPSBUeXBlLCBjb2xvciA9IFR5cGUpKSArCiAgZ2VvbV92aW9saW4oc2NhbGUgPSAid2lkdGgiLCAKICAgICAgICAgICAgICAgICNmaWxsID0gIiNlZGVkZWQiLCAKICAgICAgICAgICAgICAgIGNvbG9yID0gTkEsIGFlcyhmaWxsID0gVHlwZSksIGFscGhhID0gMC4yLCAKICAgICAgICAgICAgICB0cmltID0gRikgKwogIHRoZW1lX2xpZ2h0KCkgKyB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIsIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTAsIGhqdXN0ID0gMSwgdmp1c3QgPSAwLjUpLCBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9ibGFuaygpLCBwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9ibGFuaygpKSArIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBwYWwyKSsgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gcGFsMikgKwogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDAsIGxpbmV3aWR0aCA9IDAuMSkgKwogIHN0YXRfc3VtbWFyeShmdW4uZGF0YSA9IGlxciwgZ2VvbSA9ICJlcnJvcmJhciIsIHNob3cubGVnZW5kID0gRiwgYWVzKGNvbG9yID0gVHlwZSksIHNoYXBlID0gMjMsIHN0cm9rZSA9IDAuNSwgYWxwaGEgPSAwLjksY29sb3IgPSAiZ3JleTMwIiwgd2lkdGggPSAwLjI1KSArIAogIHN0YXRfc3VtbWFyeShmdW4uZGF0YSA9IGlxciwgZ2VvbSA9ICJwb2ludCIsIHNob3cubGVnZW5kID0gRixhZXMoZmlsbCA9IFR5cGUpLCBzaGFwZSA9IDIzLCBzdHJva2UgPSAwLjUsIGNvbG9yID0gImdyZXkzMCIsIGFscGhhID0gMC45KSAKYGBgCkNsdXN0ZXIgZnJlZSBleHByZXNzaW9uIHNoaWZ0cwoKI2NhbyRlc3RpbWF0ZUNsdXN0ZXJGcmVlRXhwcmVzc2lvblNoaWZ0cyhuLmNvcmVzID0gMjAwLCBnZW5lLnNlbGVjdGlvbiA9ICJ6Iiwgbm9ybWFsaXplLmJvdGggPSBULCBuLnRvcC5nZW5lcyA9IDMwMCkKCmBgYHtyfQojY2FvJGVzdGltYXRlQ2x1c3RlckZyZWVFeHByZXNzaW9uU2hpZnRzKG4uY29yZXMgPSAyMDAsIGdlbmUuc2VsZWN0aW9uID0gInoiLCBub3JtYWxpemUuYm90aCA9IFQsIG4udG9wLmdlbmVzID0gMzAwKQpwIDwtIGNhbyRwbG90Q2x1c3RlckZyZWVFeHByZXNzaW9uU2hpZnRzKG1pbi56ID0gMC41LCBidWlsZC5wYW5lbCA9IEYpCmdncGxvdChwW1sxXV0kZGF0YSwgYWVzKHggPSB4LCB5ID0geSwgY29sb3IgPSBDb2xvcikpICsgZ2VvbV9wb2ludCgpICsgc2NhbGVfZmlsbF9tYW51YWwoKQoKCnAxIDwtIHBbWzFdXSRkYXRhICU+JQogICAgICAgICBhcnJhbmdlKENvbG9yKSAgJT4lIGdncGxvdChhZXMoeCA9IHgsIHkgPSB5LCBjb2xvciA9IENvbG9yKSkgKyBnZW9tX3BvaW50KHNpemUgPSAwLjEpICsgc2NhbGVfY29sb3JfZ3JhZGllbnQyKG1pZCA9ICJncmV5OTAiLCBoaWdoID0gImZpcmVicmljayIsIG1pZHBvaW50ID0gMC4wMDc3LzIsIGxvdyA9ICJncmV5OTUiLCBicmVha3MgPSBjKDAsMC4wMDc3KSwgbmFtZSA9ICJaIHNjb3JlIikgKyB0aGVtZV92b2lkKCkgIyArIGd1aWRlcyhjb2xvcj1ndWlkZV9sZWdlbmQodGl0bGU9Ilogc2NvcmUiKSkKCnAyIDwtIHBbWzJdXSRkYXRhJT4lCiAgICAgICAgIGFycmFuZ2UoQ29sb3IpICU+JSBnZ3Bsb3QoYWVzKHggPSB4LCB5ID0geSwgY29sb3IgPSBDb2xvcikpICsgZ2VvbV9wb2ludChzaXplID0gMC4xKSArIHNjYWxlX2NvbG9yX2dyYWRpZW50MihtaWQgPSAiZ3JleTkwIiwgaGlnaCA9ICJmaXJlYnJpY2siLCBtaWRwb2ludCA9IDAuNiwgbG93ID0gImdyZXk5NSIsICwgbmFtZSA9ICJBZGouWiBzY29yZSIpICsgdGhlbWVfdm9pZCgpICMrIGd1aWRlcyhjb2xvcj1ndWlkZV9sZWdlbmQodGl0bGU9IkFkai5aIHNjb3JlIikpCgpsaWJyYXJ5KHBhdGNod29yaykKcDErcDIKYGBgCgpERUcgYW5hbHlzaXMKCiNjYW8kZXN0aW1hdGVERVBlckNlbGxUeXBlKG4uY29yZXMgPSAxMDAsIG5hbWUgPSAiZWRnZVIiLCBuLmNlbGxzLnN1YnNhbXBsZSA9IDUsIHJlc2FtcGxpbmcubWV0aG9kID0gImJvb3RzdHJhcCIsIG4ucmVzYW1wbGluZ3MgPSAyMCkKCgpgYGB7cn0KI2NhbyRlc3RpbWF0ZURFUGVyQ2VsbFR5cGUobi5jb3JlcyA9IDEwMCwgbmFtZSA9ICJlZGdlUiIsIG4uY2VsbHMuc3Vic2FtcGxlID0gNSwgcmVzYW1wbGluZy5tZXRob2QgPSAiYm9vdHN0cmFwIiwgbi5yZXNhbXBsaW5ncyA9IDIwKQojY2FvJHRlc3QucmVzdWx0cyRlZGdlUjIgPC0gY2FvJHRlc3QucmVzdWx0cyRlZGdlUiAlPiUgbGFwcGx5KGZ1bmN0aW9uKHgpewojICB4JHJlcyA8LSBuYS5vbWl0KHgkcmVzW29yZGVyKHgkcmVzJHN0YWIubWVkaWFuLnJhbmspLF0pCiMgIHgkcmVzJFogPC0ge3JhbmsoeCRyZXMkc3RhYi5tZWRpYW4ucmFuayklPiUgcmV2fSAqIHNpZ24oeCRyZXMkbG9nMkZvbGRDaGFuZ2UpCiMgIHJldHVybih4KQojfSkKCm5hbWVzKGNhbyR0ZXN0LnJlc3VsdHMkZWRnZVIyKSA8LSByZWNvZGUoY2FvJHRlc3QucmVzdWx0cyRlZGdlUjIgJT4lIG5hbWVzLCAhISFyZWN2ZWMpCmNhbyRwbG90TnVtYmVyT2ZERUdlbmVzKG5hbWUgPSAiZWRnZVIyIikKYGBgCmBgYHtyfQpjYW8kdGVzdC5yZXN1bHRzJGVkZ2VSMiAlPiUgbGFwcGx5KCJbWyIsICJyZXMiKSAlPiUgcmJpbmRsaXN0KC4sIGlkY29sID0gImNlbGx0eXBlIikKYGBgCmBgYHtyfQpsaWJyYXJ5KGdncmVwZWwpCmxpYnJhcnkoZ2dkaXN0KQpkYXR2b2wgPC0gY2FvJHRlc3QucmVzdWx0cyRlZGdlUjIkU3N0X0Nob2RsJHJlcyAlPiUgZGF0YS50YWJsZQoKcCA8LSBkYXR2b2wgJT4lIGdncGxvdCguLCBhZXMoeCA9IGxvZzEwKHN0YWIubWVkaWFuLnJhbmspLCB5ID0gbG9nMkZvbGRDaGFuZ2UsIGFscGhhID0gKGFicyhsb2cyRm9sZENoYW5nZSkpKSkgKyAKICBnZW9tX3BvaW50KAogICAgICAgIGFlcyhjb2xvcj0gSShpZmVsc2UoYWJzKGxvZzJGb2xkQ2hhbmdlKSA+MSwgInN0ZWVsYmx1ZTMiLCAnZ3JleTgwJykpLCBzaXplID0gKENlbGxGcmFjKSkpICsgCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gLTEsIGxpbmV0eXBlID0gImRhc2hlZCIpICsgCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMSwgbGluZXR5cGUgPSAiZGFzaGVkIikgKwogIGdlb21fbGFiZWxfcmVwZWwoZGF0YSA9IGRhdHZvbFthYnMobG9nMkZvbGRDaGFuZ2UpID4gMSxdICU+JSBoZWFkKDIwKSwgCiAgICAgICAgICAgICAgICAgICBhZXMobGFiZWwgPSBHZW5lKSwgCiAgICAgICAgICAgICAgICAgICBtYXgub3ZlcmxhcHMgPSAzMCwgCiAgICAgICAgICAgICAgICAgICBzaXplID0gMywgYWxwaGEgPSAxKSArIHlsaW0oLTQsIDQpICArIHRoZW1lX3RpZHliYXllcygpICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInRvcCIpICsgCiAgeGxhYigiU3RhYmlsaXR5IC0gbWVkaWFuIHJhbmsgb2YgZ2VuZSBieSBwIHZhbHVlIGFjcm9zcyByZXNhbXBsaW5ncyIpICsgeWxhYigiTEZDIikgCgpnZ3Jhc3RyOjpyYXN0ZXJpemUocCwgZHBpID0gMzAwKQpgYGAKCkdlbmUgb250b2xvZ3kKCiNjYW8kZXN0aW1hdGVPbnRvbG9neSh0eXBlID0gIkdTRUEiLCBuYW1lID0gIkdTRUEiLCBvcmcuZGIgPW9yZy5NbS5lZy5kYiwgdmVyYm9zZSA9IFQsIG4uY29yZXMgPSAyMDAsIGRlLm5hbWUgPSAiZWRnZVIyIikKCmBgYHtyfQojY2FvJGVzdGltYXRlT250b2xvZ3kodHlwZSA9ICJHU0VBIiwgbmFtZSA9ICJHU0VBIiwgb3JnLmRiID1vcmcuTW0uZWcuZGIsIHZlcmJvc2UgPSBULCBuLmNvcmVzID0gMjAwLCBkZS5uYW1lID0gImVkZ2VSMiIpCmNhbyRwbG90T250b2xvZ3lIZWF0bWFwKG5hbWUgPSAiR1NFQSIsIGdlbmVzID0gImFsbCIpCmBgYAoKYGBge3J9CnNzdGNob2RsYWxsIDwtIHNldE5hbWVzKGNhbyR0ZXN0LnJlc3VsdHMkR1NFQSRyZXMkU3N0X0Nob2RsICU+JSBsYXBwbHkoZnVuY3Rpb24oeCkgeEByZXN1bHQpLCBjKCJCUCIsICJDQyIsICJNRiIpKSAlPiUgcmJpbmRsaXN0KGlkY29sID0gInN1YnR5cGUiKQpzc3RjaG9kbGFsbCRwYWRqMiA8LSBzc3RjaG9kbGFsbFtvcmRlcihwdmFsdWUpLHB2YWx1ZV0gJT4lIHAuYWRqdXN0KG1ldGhvZCA9ICJCSCIpCgpwIDwtIGdncmFzdHI6OnJhc3Rlcml6ZShzc3RjaG9kbGFsbCAlPiUgZ2dwbG90KC4sIGFlcyh4ID0gTkVTLCAgeSA9IC1sb2cxMChwYWRqMiksIGNvbG9yID0gcGFkajIsIGFscGhhID0gLWxvZzEwKHBhZGoyKSwgc2l6ZSA9IC1sb2cxMChwYWRqMikpKSArIAogIGdlb21fcG9pbnQoKSArIHNjYWxlX3NpemUocmFuZ2UgPSBjKDAsIDIpKSArIAogIGdlb21fbGFiZWxfcmVwZWwoZGF0YSA9IHNzdGNob2RsYWxsW3BhZGoyIDwgMC4wNSxdLCBhZXMobGFiZWwgPSBEZXNjcmlwdGlvbiksIHNpemUgPSAyLCBhbHBoYSA9IDEsIGNvbG9yID0gImJsYWNrIikgKyAKICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAxLjMsIGxpbmV0eXBlID0gImRhc2hlZCIpICsgdGhlbWVfdGlkeWJheWVzKCkgKyAKICAgc2NhbGVfY29sb3JfZ3JhZGllbnQyKGhpZ2ggPSAibGlnaHRzdGVlbGJsdWUyIiwgbWlkID0gIndoaXRlIiwgbG93ID0gInN0ZWVsYmx1ZTQiLCBtaWRwb2ludCA9IDAuNSksIAogIGRwaSA9IDMwMCkKCmxpYnJhcnkoZ2dwbG90MikKbGlicmFyeShnZ21hZ25pZnkpCmxpYnJhcnkoZ2dwbG90MikKbGlicmFyeShnZ2ZvcmNlKQpsaWJyYXJ5KGdyaWQpCgpwMiA8LSBwICsKICBmYWNldF96b29tKHkgPSBwYWRqMiA8IDAuMDUsIHggPSBORVMgPCAtMS41LCBzcGxpdCA9IEYsIHpvb20uc2l6ZSA9IDIpCgpwMgpgYGAKYGBge3J9CiNxc2F2ZShjYW8sICJjYW9faW5oLnFzIikKYGBgCg==